From 1a3f140de38dcdb13d7c1f6f613f278e1ff0cc49 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Fri, 18 Jul 2025 18:05:38 +0100 Subject: [PATCH] weston: fix crash on RaspberryPi 3 with VC4 DRM driver See issue: https://gitlab.freedesktop.org/wayland/weston/-/issues/1024 Patches imported are: https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/1621 Hopefully they will be part of an 14.0.3 release. Signed-off-by: Daniel Golle --- frameworks/weston/Makefile | 2 +- ...other-planes-that-may-support-fences.patch | 25 +++ ...few-dma-buf-feedback-failure-reasons.patch | 72 ++++++++ ...x-issue-with-enum-being-wrongly-used.patch | 29 +++ ...-avoid-dma-buf-feedback-endless-loop.patch | 172 ++++++++++++++++++ 5 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 frameworks/weston/patches/001-drm-try-other-planes-that-may-support-fences.patch create mode 100644 frameworks/weston/patches/002-drm-fix-a-few-dma-buf-feedback-failure-reasons.patch create mode 100644 frameworks/weston/patches/003-drm-fix-issue-with-enum-being-wrongly-used.patch create mode 100644 frameworks/weston/patches/004-drm-avoid-dma-buf-feedback-endless-loop.patch diff --git a/frameworks/weston/Makefile b/frameworks/weston/Makefile index 3ae7c61..03f20f1 100644 --- a/frameworks/weston/Makefile +++ b/frameworks/weston/Makefile @@ -1,7 +1,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=weston -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_VERSION:=14.0.2 PKG_MAJOR_VERSION:=$(firstword $(subst .,$(space),$(PKG_VERSION))) diff --git a/frameworks/weston/patches/001-drm-try-other-planes-that-may-support-fences.patch b/frameworks/weston/patches/001-drm-try-other-planes-that-may-support-fences.patch new file mode 100644 index 0000000..aabc74a --- /dev/null +++ b/frameworks/weston/patches/001-drm-try-other-planes-that-may-support-fences.patch @@ -0,0 +1,25 @@ +From 8f1a08991789cde7652ff4ccb9a9a46abe18d74e Mon Sep 17 00:00:00 2001 +From: Leandro Ribeiro +Date: Mon, 23 Sep 2024 17:06:31 -0300 +Subject: [PATCH 1/4] drm: try other planes that may support fences + +Do not skip all the planes if a single one of them do not support +fences. The other may do. + +Signed-off-by: Leandro Ribeiro +(cherry picked from commit b347af2ce0fca3c7616d5a4d6500ca8770ad3252) +--- + libweston/backend-drm/state-propose.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/libweston/backend-drm/state-propose.c ++++ b/libweston/backend-drm/state-propose.c +@@ -595,7 +595,7 @@ drm_output_find_plane_for_view(struct dr + plane->props[WDRM_PLANE_IN_FENCE_FD].prop_id == 0) { + drm_debug(b, "\t\t\t\t[%s] not placing view %p on %s: " + "no in-fence support\n", p_name, ev, p_name); +- return NULL; ++ continue; + } + + if (!b->has_underlay && mm_has_underlay) { diff --git a/frameworks/weston/patches/002-drm-fix-a-few-dma-buf-feedback-failure-reasons.patch b/frameworks/weston/patches/002-drm-fix-a-few-dma-buf-feedback-failure-reasons.patch new file mode 100644 index 0000000..3ae82ef --- /dev/null +++ b/frameworks/weston/patches/002-drm-fix-a-few-dma-buf-feedback-failure-reasons.patch @@ -0,0 +1,72 @@ +From 6445af1eade0fcdcc522cd9c1d45d840b87190bb Mon Sep 17 00:00:00 2001 +From: Leandro Ribeiro +Date: Tue, 24 Sep 2024 10:08:05 -0300 +Subject: [PATCH 2/4] drm: fix a few dma-buf feedback failure reasons + +There are a few points in the code where we are wrongly using +FAILURE_REASONS_ADD_FB_FAILED, probably because we didn't have so many +"failure reasons" previously. This update such cases to use enum's that +make sense. + +Signed-off-by: Leandro Ribeiro +(cherry picked from commit 3210cec531702177d24c42bb56486124eda00f19) +--- + libweston/backend-drm/drm-internal.h | 11 ++++++----- + libweston/backend-drm/state-propose.c | 8 ++++---- + 2 files changed, 10 insertions(+), 9 deletions(-) + +--- a/libweston/backend-drm/drm-internal.h ++++ b/libweston/backend-drm/drm-internal.h +@@ -163,11 +163,12 @@ enum try_view_on_plane_failure_reasons { + FAILURE_REASONS_INADEQUATE_CONTENT_PROTECTION = 1 << 6, + FAILURE_REASONS_INCOMPATIBLE_TRANSFORM = 1 << 7, + FAILURE_REASONS_NO_BUFFER = 1 << 8, +- FAILURE_REASONS_BUFFER_TYPE = 1 << 9, +- FAILURE_REASONS_GLOBAL_ALPHA = 1 << 10, +- FAILURE_REASONS_NO_GBM = 1 << 11, +- FAILURE_REASONS_GBM_BO_IMPORT_FAILED = 1 << 12, +- FAILURE_REASONS_GBM_BO_GET_HANDLE_FAILED = 1 << 13, ++ FAILURE_REASONS_BUFFER_TOO_BIG = 1 << 9, ++ FAILURE_REASONS_BUFFER_TYPE = 1 << 10, ++ FAILURE_REASONS_GLOBAL_ALPHA = 1 << 11, ++ FAILURE_REASONS_NO_GBM = 1 << 12, ++ FAILURE_REASONS_GBM_BO_IMPORT_FAILED = 1 << 13, ++ FAILURE_REASONS_GBM_BO_GET_HANDLE_FAILED = 1 << 14, + }; + + /** +--- a/libweston/backend-drm/state-propose.c ++++ b/libweston/backend-drm/state-propose.c +@@ -419,7 +419,7 @@ drm_output_find_plane_for_view(struct dr + /* check view for valid buffer, doesn't make sense to even try */ + if (!weston_view_has_valid_buffer(ev)) { + pnode->try_view_on_plane_failure_reasons |= +- FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE; ++ FAILURE_REASONS_NO_BUFFER; + return NULL; + } + +@@ -431,12 +431,12 @@ drm_output_find_plane_for_view(struct dr + buffer = ev->surface->buffer_ref.buffer; + if (buffer->type == WESTON_BUFFER_SOLID) { + pnode->try_view_on_plane_failure_reasons |= +- FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE; ++ FAILURE_REASONS_BUFFER_TYPE; + return NULL; + } else if (buffer->type == WESTON_BUFFER_SHM) { + if (!output->cursor_plane || device->cursors_are_broken) { + pnode->try_view_on_plane_failure_reasons |= +- FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE; ++ FAILURE_REASONS_BUFFER_TYPE; + return NULL; + } + +@@ -457,7 +457,7 @@ drm_output_find_plane_for_view(struct dr + "(buffer (%dx%d) too large for cursor plane)\n", + ev, buffer->width, buffer->height); + pnode->try_view_on_plane_failure_reasons |= +- FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE; ++ FAILURE_REASONS_BUFFER_TOO_BIG; + return NULL; + } + diff --git a/frameworks/weston/patches/003-drm-fix-issue-with-enum-being-wrongly-used.patch b/frameworks/weston/patches/003-drm-fix-issue-with-enum-being-wrongly-used.patch new file mode 100644 index 0000000..7994eb8 --- /dev/null +++ b/frameworks/weston/patches/003-drm-fix-issue-with-enum-being-wrongly-used.patch @@ -0,0 +1,29 @@ +From 0b5c47edcaf0e197f601fbf82bb3c52da8d93c87 Mon Sep 17 00:00:00 2001 +From: Leandro Ribeiro +Date: Tue, 24 Sep 2024 10:08:51 -0300 +Subject: [PATCH 3/4] drm: fix issue with enum being wrongly used + +FAILURE_REASONS_ADD_FB_FAILED is defined as (1 << 3), so when we are +accumulating "failure reasons" in a variable we don't need to do the bit +shift again. + +This results in an issue, because (1 << FAILURE_REASONS_ADD_FB_FAILED) +results in (1 << (1 << 3)) == (1 << 8). + +Signed-off-by: Leandro Ribeiro +(cherry picked from commit 8b83bb5cebe64b672e978dc3423afe97d6178b7e) +--- + libweston/backend-drm/fb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/libweston/backend-drm/fb.c ++++ b/libweston/backend-drm/fb.c +@@ -742,7 +742,7 @@ drm_fb_get_from_paint_node(struct drm_ou + fb = drm_fb_get_from_bo(bo, device, is_opaque, BUFFER_CLIENT); + if (!fb) { + pnode->try_view_on_plane_failure_reasons |= +- (1 << FAILURE_REASONS_ADD_FB_FAILED); ++ FAILURE_REASONS_ADD_FB_FAILED; + gbm_bo_destroy(bo); + goto unsuitable; + } diff --git a/frameworks/weston/patches/004-drm-avoid-dma-buf-feedback-endless-loop.patch b/frameworks/weston/patches/004-drm-avoid-dma-buf-feedback-endless-loop.patch new file mode 100644 index 0000000..4bd1851 --- /dev/null +++ b/frameworks/weston/patches/004-drm-avoid-dma-buf-feedback-endless-loop.patch @@ -0,0 +1,172 @@ +From 1a9149cc062ac744ab190c8b2dc34102ca8a0adc Mon Sep 17 00:00:00 2001 +From: Leandro Ribeiro +Date: Tue, 24 Sep 2024 11:23:50 -0300 +Subject: [PATCH 4/4] drm: avoid dma-buf feedback endless loop + +Currently we have the following situation: we add a scanout tranche +because if the client re-allocates with another format/modifier, the +chances of being placed in a DRM/KMS plane is higher. + +But then we run out of overlay planes. So we remove the scanout tranche, +because the format/modifier available in the renderer tranche are +optimal for rendering. + +Now Weston detects again that the format/modifier is what may be +avoiding the view being place in a plane, re-adding the scanout tranche. +And we have an endless loop. + +To avoid this, let's accumulate the reasons why placing the view in a +place failed. So if we detect that we don't have planes available, no +matter the format/modifier, we won't add the scanout tranche. + +Signed-off-by: Leandro Ribeiro +(cherry picked from commit d3ead778dea9bde77d318292b8870e746cad5c3d) +--- + libweston/backend-drm/state-propose.c | 55 +++++++++++---------------- + 1 file changed, 23 insertions(+), 32 deletions(-) + +--- a/libweston/backend-drm/state-propose.c ++++ b/libweston/backend-drm/state-propose.c +@@ -413,9 +413,15 @@ drm_output_find_plane_for_view(struct dr + + bool view_matches_entire_output, scanout_has_view_assigned; + uint32_t possible_plane_mask = 0; ++ bool any_candidate_picked = false; + + pnode->try_view_on_plane_failure_reasons = FAILURE_REASONS_NONE; + ++ /* filter out non-cursor views in renderer-only mode */ ++ if (mode == DRM_OUTPUT_PROPOSE_STATE_RENDERER_ONLY && ++ ev->layer_link.layer != &b->compositor->cursor_layer) ++ return NULL; ++ + /* check view for valid buffer, doesn't make sense to even try */ + if (!weston_view_has_valid_buffer(ev)) { + pnode->try_view_on_plane_failure_reasons |= +@@ -423,32 +429,23 @@ drm_output_find_plane_for_view(struct dr + return NULL; + } + +- /* filter out non-cursor views in renderer-only mode */ +- if (mode == DRM_OUTPUT_PROPOSE_STATE_RENDERER_ONLY && +- ev->layer_link.layer != &b->compositor->cursor_layer) +- return NULL; +- + buffer = ev->surface->buffer_ref.buffer; + if (buffer->type == WESTON_BUFFER_SOLID) { + pnode->try_view_on_plane_failure_reasons |= + FAILURE_REASONS_BUFFER_TYPE; +- return NULL; + } else if (buffer->type == WESTON_BUFFER_SHM) { +- if (!output->cursor_plane || device->cursors_are_broken) { ++ if (!output->cursor_plane || device->cursors_are_broken) + pnode->try_view_on_plane_failure_reasons |= + FAILURE_REASONS_BUFFER_TYPE; +- return NULL; +- } + +- /* Even though this is a SHM buffer, pixel_format stores the +- * format code as DRM FourCC */ ++ /* Even though this is a SHM buffer, pixel_format stores ++ * the format code as DRM FourCC */ + if (buffer->pixel_format->format != DRM_FORMAT_ARGB8888) { + drm_debug(b, "\t\t\t\t[view] not placing view %p on " +- "plane; SHM buffers must be ARGB8888 for " ++ "plane; SHM buffers must be ARGB8888 for " + "cursor view\n", ev); + pnode->try_view_on_plane_failure_reasons |= + FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE; +- return NULL; + } + + if (buffer->width > device->cursor_width || +@@ -458,10 +455,10 @@ drm_output_find_plane_for_view(struct dr + ev, buffer->width, buffer->height); + pnode->try_view_on_plane_failure_reasons |= + FAILURE_REASONS_BUFFER_TOO_BIG; +- return NULL; + } + +- possible_plane_mask = (1 << output->cursor_plane->plane_idx); ++ if (pnode->try_view_on_plane_failure_reasons == FAILURE_REASONS_NONE) ++ possible_plane_mask = (1 << output->cursor_plane->plane_idx); + } else { + if (mode == DRM_OUTPUT_PROPOSE_STATE_RENDERER_ONLY) { + drm_debug(b, "\t\t\t\t[view] not assigning view %p " +@@ -477,20 +474,16 @@ drm_output_find_plane_for_view(struct dr + possible_plane_mask |= 1 << plane->plane_idx; + } + +- if (!possible_plane_mask) { ++ if (!possible_plane_mask) + pnode->try_view_on_plane_failure_reasons |= + FAILURE_REASONS_INCOMPATIBLE_TRANSFORM; +- return NULL; +- } + + fb = drm_fb_get_from_paint_node(state, pnode); +- if (!fb) { ++ if (fb) ++ possible_plane_mask &= fb->plane_mask; ++ else + drm_debug(b, "\t\t\t[view] couldn't get FB for view: 0x%lx\n", +- (unsigned long) pnode->try_view_on_plane_failure_reasons); +- return NULL; +- } +- +- possible_plane_mask &= fb->plane_mask; ++ (unsigned long) pnode->try_view_on_plane_failure_reasons); + } + + view_matches_entire_output = +@@ -521,7 +514,6 @@ drm_output_find_plane_for_view(struct dr + assert(plane == output->cursor_plane); + break; + case WDRM_PLANE_TYPE_PRIMARY: +- assert(fb); + if (plane != output->scanout_plane) + continue; + if (mode != DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY) +@@ -530,7 +522,6 @@ drm_output_find_plane_for_view(struct dr + continue; + break; + case WDRM_PLANE_TYPE_OVERLAY: +- assert(fb); + assert(mode != DRM_OUTPUT_PROPOSE_STATE_RENDERER_ONLY); + /* if the view covers the whole output, put it in the + * scanout plane, not overlay */ +@@ -613,6 +604,7 @@ drm_output_find_plane_for_view(struct dr + else + zpos = MIN(current_lowest_zpos - 1, plane->zpos_max); + ++ any_candidate_picked = true; + drm_debug(b, "\t\t\t\t[plane] plane %d picked " + "from candidate list, type: %s\n", + plane->plane_id, p_name); +@@ -620,9 +612,10 @@ drm_output_find_plane_for_view(struct dr + if (plane->type == WDRM_PLANE_TYPE_CURSOR) { + ps = drm_output_prepare_cursor_paint_node(state, pnode, zpos); + } else { +- ps = drm_output_try_paint_node_on_plane(plane, state, +- pnode, mode, +- fb, zpos); ++ if (fb) ++ ps = drm_output_try_paint_node_on_plane(plane, state, ++ pnode, mode, ++ fb, zpos); + } + + if (ps) { +@@ -641,11 +634,9 @@ drm_output_find_plane_for_view(struct dr + FAILURE_REASONS_PLANES_REJECTED; + } + +- if (!ps && +- pnode->try_view_on_plane_failure_reasons == FAILURE_REASONS_NONE) { ++ if (!any_candidate_picked) + pnode->try_view_on_plane_failure_reasons |= + FAILURE_REASONS_NO_PLANES_AVAILABLE; +- } + + /* if we have a plane state, it has its own ref to the fb; if not then + * we drop ours here */ -- 2.30.2